#ifndef __CM_NAT_HOST_LINK_H__
#define __CM_NAT_HOST_LINK_H__

#include "Link.h"
#include "StunAgent.h"
#include "cm_base/UDPPort.h"
#include "Poco/Mutex.h"
#include "Poco/Net/IPAddress.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/NetworkInterface.h"

using Poco::Mutex;
using Poco::Net::IPAddress;
using Poco::Net::SocketReactor;
using Poco::Net::NetworkInterface;

namespace cm_nat
{
    class HostLink;

    class HostLinkListener
    {
    public:
        virtual void onReceive(ByteBuffer* data) =0;
        virtual void onCheckResult( HostLink* link, int result ) =0;
        
        enum
        {
            CHECK_RES_CHECK_FAIL,   //connect fail
            CHECK_RES_CHECK_SUCCESS,//connection setup
            CHECK_RES_KEEP_FAIL
        };
    };

    class HostLink: public Link, public UDPPortListener, public StunAgentListener
    {
    public:
        HostLink( ByteBufferPool* p_pool, SocketReactor* reactor, BaseTimer* p_timer );
        ~HostLink();

        int setup( IPAddress host_ip );
        int setup( NetworkInterface nic);
        int teardown();

        void registerListener(HostLinkListener* p_listener);

        SocketAddress getHostAddress();

        int checkConnection( SocketAddress peer );

        //from Link
        int send(ByteBuffer* data);

        //from UDPPortListener
        void onReceive(UDPPort*p_port, ByteBuffer* p_data);

        //from StunAgentListener
        void onToSend(StunAgent* p_agent, ByteBuffer* data, SocketAddress sa);
        void onCheckResult(StunAgent* p_agent, int result);

    protected:
        ByteBufferPool* m_bufferPool;
        SocketReactor* m_reactor;

        HostLinkListener* m_listener ;

        UDPPort* m_port;
        StunAgent* m_agent;

        SocketAddress m_peerAddress;
        SocketAddress m_hostAddress;

        BaseTimer* m_timer;

    };
}

#endif